package com.hmjk.health.health;

import java.util.Calendar;

import com.hmjk.health.HealthApp;
import com.hmjk.health.R;
import com.hmjk.health.background.DataManager;
import com.hmjk.health.util.BP_Evaluator;
import com.hmjk.health.util.BP_Reference;
import com.hmjk.health.util.BloodPressureData;
import com.hmjk.health.util.HEALTH_KEY;
import com.hmjk.health.util.MULTI_USER_DEV_DATA;
import com.hmjk.health.util.BloodPressureData.BP_DETAIL;
import com.hmjk.health.views.BP_GraphView;
import com.hmjk.health.views.BP_GraphView.ICoallBack;
import com.hmjk.health.views.BpBarView;
import com.hmjk.health.views.GluCakyLayout;
import com.hmjk.health.views.RefreshLayout;
import com.hmjk.health.views.RefreshLayout.OnRefreshListener;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.text.format.Time;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;



public class HealthCardBloodPressureOverViewFragment extends Fragment {
    private static final String TAG = HealthCardBloodPressureOverViewFragment.class.getSimpleName();
    
    private HealthApp mApp;
    private boolean attached = false;
    
    private RefreshLayout refresh;
    private String refreshing = null;
    private MULTI_USER_DEV_DATA mUserAccount = null;
    private BloodPressureData bpData = null;
    private int queryHealthBPstatus = 0; //0 not query, 1 querying 2 finish
    private BP_DETAIL[] bpArray = new BP_DETAIL[7];
    
    private final long SEC_TIME_ONE_DAY = (long)(24 * 60 * 60 * 1000);
    
    //Latest Views
    private TextView mDateLatest = null;
    private TextView mAgegroupLatest = null;
    private TextView mGendarLatest = null;
    private TextView mSbpLatest = null, mDbpLatest = null;
    private BpBarView mBarLatest = null;
    
    //One week Views
    private BP_GraphView mGraphView = null;
    private TextView mWeekTime = null;
    private TextView mSelectDate = null;
    private TextView mSbpWeek = null, mDbpWeek = null, mPulseWeek = null;
    private ImageView mSbpWeekHint = null, mDbpWeekHint = null;
    
    //One month Views
    private TextView mSbpHigh = null, mSbpLow = null, mSbpAver = null;
    private TextView mDbpHigh = null, mDbpLow = null, mDbpAver = null;
    private GluCakyLayout mBpMonth = null;

    public HealthCardBloodPressureOverViewFragment(HealthApp app){
    	super();
    	mApp = app;
    }
    
    private void logd(String info){
		Log.d(TAG,info);
	}
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "TestFragment-----onCreate");
      
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        Log.d(TAG, "TestFragment-----onCreateView");
        View view = inflater.inflate(R.layout.health_bp_overview, container, false);
        
        Bundle args = getArguments();
        mUserAccount =  (MULTI_USER_DEV_DATA) args.getSerializable("account");
        
        
        //Latest Views
        mDateLatest = (TextView)view.findViewById(R.id.newdate);
        mAgegroupLatest = (TextView)view.findViewById(R.id.reference_content);
        mGendarLatest = (TextView)view.findViewById(R.id.gendar);
        mSbpLatest = (TextView)view.findViewById(R.id.sbp_newvalue);
        mDbpLatest = (TextView)view.findViewById(R.id.dbp_newvalue);
        mBarLatest = (BpBarView)view.findViewById(R.id.bpbar);
        
        //One week Views
        mWeekTime = (TextView)view.findViewById(R.id.weektime);
        mSelectDate = (TextView)view.findViewById(R.id.select_date);
        mSbpWeek = (TextView)view.findViewById(R.id.oneweek_sbp_value);
        mDbpWeek = (TextView)view.findViewById(R.id.oneweek_dbp_value);
        mPulseWeek = (TextView)view.findViewById(R.id.oneweek_pulse_value);
        mSbpWeekHint = (ImageView)view.findViewById(R.id.oneweek_sbp_hint);
        mDbpWeekHint = (ImageView)view.findViewById(R.id.oneweek_dbp_hint);
        mGraphView = (BP_GraphView)view.findViewById(R.id.bp_graph_view);
        mGraphView.setonClick(new ICoallBack() {
			
			@Override
			public void onClickButton(int i) {
				// TODO Auto-generated method stub
				if(bpArray[i] != null){
					updateWeekSelectionInfoView(i);
				}
			}
		});
        
        //One month Views
        mSbpHigh = (TextView)view.findViewById(R.id.month_sbp_high_value);
        mSbpAver = (TextView)view.findViewById(R.id.month_sbp_average_value);
        mSbpLow = (TextView)view.findViewById(R.id.month_sbp_low_value);
        mDbpHigh = (TextView)view.findViewById(R.id.month_dbp_high_value);
        mDbpAver = (TextView)view.findViewById(R.id.month_dbp_average_value);
        mDbpLow = (TextView)view.findViewById(R.id.month_dbp_low_value);
        mBpMonth = (GluCakyLayout)view.findViewById(R.id.monthgraphic);

        refresh = (RefreshLayout)view.findViewById(R.id.refresh_root);
		refresh.initScroll();
		refreshing = null;
		refresh.setOnRefreshListener(new OnRefreshListener() {
			
			@Override
			public void onRefresh() {
				refreshing = null;
				
				if(mUserAccount != null){
					HEALTH_KEY key = new HEALTH_KEY(mUserAccount.id, mUserAccount.subcode);
					boolean ok = mApp.getDataManager().refreshData(DataManager.F_BP_DATA, key);
					if(ok){
						refreshing = new String(DataManager.F_BP_DATA);
						
					}					
				}
				
				if(refreshing == null){
					Message m = mhandler.obtainMessage(MSG_CLOSE_REFRESH_VIEW);
					mhandler.sendMessageDelayed(m, 500);
				}
			}
		});
        
        return view;

    }
    
    private void updateWeekSelectionInfoView(int i){
    	Calendar c = Calendar.getInstance();
		c.setTimeInMillis(bpArray[i].recordtime);
		String s = getResources().getString(R.string.measure_value_date, c.get(Calendar.MONTH) + 1, c.get(Calendar.DAY_OF_MONTH));
		mSelectDate.setText(s);
		mSbpWeek.setText("" + bpArray[i].sbp);
		int value = BP_Evaluator.checkSBP(bpArray[i].sbp);
		if(value == BP_Evaluator.LEV_HIGH){
			mSbpWeekHint.setVisibility(View.VISIBLE);
			mSbpWeekHint.setImageResource(R.drawable.health_toohigh);
		}else if(value == BP_Evaluator.LEV_LOW){
			mSbpWeekHint.setVisibility(View.VISIBLE);
			mSbpWeekHint.setImageResource(R.drawable.health_toolow);
		}else {
			mSbpWeekHint.setVisibility(View.GONE);
		}
		mDbpWeek.setText("" + bpArray[i].dbp);
		value = BP_Evaluator.checkDBP(bpArray[i].dbp);
		if(value == BP_Evaluator.LEV_HIGH){
			mDbpWeekHint.setVisibility(View.VISIBLE);
			mDbpWeekHint.setImageResource(R.drawable.health_toohigh);
		}else if(value == BP_Evaluator.LEV_LOW){
			mDbpWeekHint.setVisibility(View.VISIBLE);
			mDbpWeekHint.setImageResource(R.drawable.health_toolow);
		}else {
			mDbpWeekHint.setVisibility(View.GONE);
		}
		mPulseWeek.setText("" + bpArray[i].pulse);
    }
    
    public void focusChange(boolean focus){
		refreshing = null;
		if(refresh != null)
			refresh.stopRefreshing();
		if(focus && (mUserAccount != null)){
			queryBpData(mUserAccount.id, mUserAccount.subcode, false);
		}
		
	}
    
    public void queryBpData(String tid, String subcode, boolean force){
    	logd("queryBpData tid=" + tid + " subcode= "+subcode);
    	boolean update = false;
    	
    	logd("queryBpData queryHealthBPstatus=" + queryHealthBPstatus + " force= "+force);
		if((queryHealthBPstatus == 0) || force){
			HEALTH_KEY key = new HEALTH_KEY(tid, subcode);
			boolean ok = mApp.getDataManager().refreshData(DataManager.F_BP_DATA, key);
			
			if(ok){
				logd("queryHealthBPData querying");
				queryHealthBPstatus = 1;
				update = true;
			}else{
				logd("queryHealthBPData no need");
				queryHealthBPstatus = 2;
			}
		}
		
		if(update){
			updateDataRoomView();
		}
    }
    
    private final int MSG_CLOSE_REFRESH_VIEW = 411;
	
	private Handler mhandler = new Handler(){
		@Override
		public void handleMessage(Message msg){
			switch(msg.what){
			case MSG_CLOSE_REFRESH_VIEW:{
				cancelRefresh();
			}
			break;
			}
		}
	};
	
	public boolean cancelRefresh(){
		refreshing = null;
		if((refresh != null) && refresh.isRefreshing()){
			refresh.stopRefreshing();
			return true;
		}
		return false;
	}
	
	public boolean isRefreshing(){
		if(refresh != null)
			return refresh.isRefreshing();
		
		return false;
	}
	
	private void updateRefreshFlag(String clear){
		if(refreshing == null){
			logd("updateRefreshFlag, refreshing is null");
			return;
		}
		logd("updateRefreshFlag clear=" + clear);
		
		if(refreshing.contains(clear)){
			String[] ss = refreshing.split(":");
			String flag = "";
			for(String s:ss){
				if(s.equalsIgnoreCase(clear) == false){
					if(flag.equals("") == false){
						flag += ":";
					}
					flag += s;
				}
			}
			if(flag.trim().isEmpty())
				refreshing = null;
			else{
				refreshing = flag.trim();
			}
		}
	}
	
	public void refreshResult(String tag, boolean update){
		if(DataManager.F_BP_DATA.equals(tag)){
			if(update){
				if(refreshing != null){
					updateRefreshFlag(tag);
					if(refreshing == null){
						cancelRefresh();
						
						queryBpDataDone(DataManager.F_BP_DATA, update);
					}
				}else {
					queryBpDataDone(DataManager.F_BP_DATA, update);
				}
			}
		}
	}

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "TestFragment-----onDestroy");
    }

    /*
    @Override
    public void onAttach(Context context) {
    	// TODO Auto-generated method stub
    	super.onAttach(context);
    	attached = true;
    }*/
    
    public void onAttach(Activity a) {
    	// TODO Auto-generated method stub
    	super.onAttach(a);
    	attached = true;
    }
    
    @Override
    public void onDetach() {
    	// TODO Auto-generated method stub
    	super.onDetach();
    	attached = false;
    }
    
    @Override
    public void onResume() {
    	// TODO Auto-generated method stub
    	super.onResume();
    	
    	//test code
    	queryBpDataDone(DataManager.F_BP_DATA, true);
    }
    
    private int birthday2Age(String birthday){
		int pos = birthday.indexOf("-");
		String years = birthday.substring(0, pos);
		int yeari = Integer.parseInt(years);
		Time time = new Time();
		time.setToNow();
		int age = time.year - yeari;
		return age;
	}
    
    private long getTimeInMillis(int year, int month, int day){
		Calendar c = Calendar.getInstance();
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, month);
		c.set(Calendar.DATE, day);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		
		return c.getTimeInMillis();
	}
    
    private void queryBpDataDone(String tag, boolean updated){
    	if(DataManager.F_BP_DATA.equals(tag)){
			queryHealthBPstatus = 2;
		}
    	
    	if(queryHealthBPstatus == 2){
    		if(updated){
    			updateBpData();
    		}
    		updateDataRoomView();
    	}
    }
    
    private void updateBpData(){
    	if(mUserAccount == null){
    		return;
    	}
    	
		Calendar c = Calendar.getInstance();
		long timeNow = c.getTimeInMillis();
		long timeFrom = getTimeInMillis(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH)) - 30 * SEC_TIME_ONE_DAY;
		String[] argStrings = new String[]{mUserAccount.id, mUserAccount.subcode, String.valueOf(timeFrom), String.valueOf(timeNow)};
		bpData = (BloodPressureData) mApp.getDataManager().checkData(DataManager.F_BP_DATA, argStrings);
	}
    
    private void updateDataRoomView(){
    	if(mUserAccount == null){
    		logd("updateDataRoomView mUserAccount is null!");
    		return;
    	}
    	
    	if(attached == false){
    		logd("updateDataRoomView attached is false!");
			return;
    	}
    	
    	if(bpData == null){
    		logd("updateDataRoomView bpData is null!");
    		return;
    	}
    	logd("updateDataRoomView bpData:" + bpData);
    	
    	updateBpLatestView();
    	updateBpWeekView();
    	updateBpMonthView();
    }
    
    private void updateBpLatestView(){
    	
    	BP_DETAIL bp = bpData.getLatestBpvalue();
    	if(bp == null){
    		logd("updateBpLatestView no BP_DETAIL!");
    		return;
    	}
    	
    	logd("updateBpLatestView bp:" + bp);
    	Calendar c = Calendar.getInstance();
		long timeToday0 = getTimeInMillis(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
		String tmpString = "";
		
		//date
		Time t = new Time();
		t.set(bp.recordtime);
		if((bp.recordtime  >=  timeToday0) && (bp.recordtime < (timeToday0 + SEC_TIME_ONE_DAY))){
			tmpString = getResources().getString(R.string.measure_today);
		}else if((bp.recordtime  <  timeToday0) && (bp.recordtime > (timeToday0 - SEC_TIME_ONE_DAY))){
			tmpString = getResources().getString(R.string.measure_yestoday);
		}else {
			tmpString = String.valueOf(t.year) + "-" + String.valueOf(t.month + 1) + "-" + String.valueOf(t.monthDay);
		}
		mDateLatest.setText(tmpString);
		
		//bpbarview
		mBarLatest.setBpValue(bp.sbp, bp.dbp, bp.pulse);
    	
		//reference
		if((mUserAccount.birthday.isEmpty() == false) && (mUserAccount.gender.isEmpty() == false)){
			
			int[] values = BP_Reference.checkAgeGroup(birthday2Age(mUserAccount.birthday), mUserAccount.gender);
			tmpString = values[0] + " ~ " + values[1] + getResources().getString(R.string.bp_reference_age);
			mAgegroupLatest.setText(tmpString);
			
			if(mUserAccount.gender.equalsIgnoreCase("F")){
				tmpString = getResources().getString(R.string.bp_reference_gendar_f);
			}else {
				tmpString = getResources().getString(R.string.bp_reference_gendar_m);
			}
			mGendarLatest.setText(tmpString);
			
			mSbpLatest.setText("" + values[2]);
			mDbpLatest.setText("" + values[3]);
			
		}else {
			tmpString = getResources().getString(R.string.measure_null_value);
			mAgegroupLatest.setText(tmpString);
			mGendarLatest.setText(tmpString);
			mSbpLatest.setText(tmpString);
			mDbpLatest.setText(tmpString);
		}
		
    }
    
    private void updateBpWeekView(){
    	
    	Calendar c = Calendar.getInstance();
    	long timeNow = c.getTimeInMillis();
		long timeToday0 = getTimeInMillis(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
		String timeEnd = getResources().getString(R.string.measure_value_date, c.get(Calendar.MONTH) + 1, c.get(Calendar.DAY_OF_MONTH));
		c.setTimeInMillis(timeToday0 - 6 * SEC_TIME_ONE_DAY);
		String timeStart = getResources().getString(R.string.measure_value_date, c.get(Calendar.MONTH) + 1, c.get(Calendar.DAY_OF_MONTH));
		
		mWeekTime.setText(timeStart + " ~ " + timeEnd);
		
		for(BP_DETAIL bp: bpData.getDataList()){
			for(int i = 6; i >= 0; i --){
				if(bp.recordtime < timeToday0 - 6 * SEC_TIME_ONE_DAY){
					break;
				}
				long t = timeToday0 - (i - 1) * SEC_TIME_ONE_DAY;
				if(i == 0){
					t = timeNow;
				}
				if((bp.recordtime >= timeToday0 - i * SEC_TIME_ONE_DAY) && (bp.recordtime < t)){
					bpArray[6 - i] = bp;
				}
			}
		}
		
		mGraphView.clear_BloodPressure_Graph();
		int index = -1;
//		for(int i = 0; i < 7; i ++){
//			if(bpArray[i] != null){
//				mGraphView.setBloodPressure(i, bpArray[i].sbp, bpArray[i].dbp, true);
//				index = i;
//			}
//		}
		index =mGraphView.setBloodPressure(bpArray);
		if(index >= 0){
			mGraphView.setBloodPressureFocus(index);
			updateWeekSelectionInfoView(index);
		}
    	
    }
    
    private void updateBpMonthView(){
    	int sbpValueTotal = 0, dbpValueTotal = 0;
    	int sbpValueHigh = 0, sbpValueLow = 0, sbpValueAver = 0;
    	int dbpValueHigh = 0, dbpValueLow = 0, dbpValueAver = 0;
    	int lbp = 0, normal = 0, morhigh = 0, hbpi = 0, hbpii = 0, hbpiii = 0;

    	BP_DETAIL latest = bpData.getLatestBpvalue();
    	if(latest != null){
    		sbpValueHigh = latest.sbp;
    		sbpValueLow = latest.sbp;
    		dbpValueHigh = latest.dbp;
    		dbpValueLow = latest.dbp;
    	}
    	
    	for(BP_DETAIL bp:bpData.getDataList()){
    		sbpValueTotal += bp.sbp;
    		if(bp.sbp > sbpValueHigh){
    			sbpValueHigh = bp.sbp;
    		}else if (bp.sbp < sbpValueLow) {
				sbpValueLow = bp.sbp;
			}
    		dbpValueTotal += bp.dbp;
    		if(bp.dbp > dbpValueHigh){
    			dbpValueHigh = bp.dbp;
    		}else if (bp.dbp < dbpValueLow) {
				dbpValueLow = bp.dbp;
			}
    		
    		switch (BP_Evaluator.evaluateLevel(bp.sbp, bp.dbp).type) {
			case BP_Evaluator.TYPE_LOW:{
				lbp ++;
			}break;
			
			case BP_Evaluator.TYPE_NORMAL:{
				normal ++;
			}break;
			
			case BP_Evaluator.TYPE_NORMALHIGH:{
				morhigh ++;
			}break;
			
			case BP_Evaluator.TYPE_1HIGH:{
				hbpi ++;
			}break;
			
			case BP_Evaluator.TYPE_2HIGH:{
				hbpii ++;
			}break;
			
			case BP_Evaluator.TYPE_3HIGH:{
				hbpiii ++;
			}break;
			}
    	}
    	if(bpData.getListSize() > 0){
    		sbpValueAver = sbpValueTotal / bpData.getListSize();
    		dbpValueAver = dbpValueTotal / bpData.getListSize();
    		mSbpHigh.setText("" + sbpValueHigh);
        	mSbpLow.setText("" + sbpValueLow);
        	mDbpHigh.setText("" + dbpValueHigh);
        	mDbpLow.setText("" + dbpValueLow);
        	mSbpAver.setText("" + sbpValueAver);
        	mDbpAver.setText("" + dbpValueAver);
    	}else {
    		mSbpHigh.setText("" + getResources().getString(R.string.measure_null_value));
        	mSbpLow.setText("" + getResources().getString(R.string.measure_null_value));
        	mDbpHigh.setText("" + getResources().getString(R.string.measure_null_value));
        	mDbpLow.setText("" + getResources().getString(R.string.measure_null_value));
        	mSbpAver.setText("" + getResources().getString(R.string.measure_null_value));
        	mDbpAver.setText("" + getResources().getString(R.string.measure_null_value));
		}    	
    	
    	mBpMonth.setParameters(normal, morhigh, hbpi, hbpii, hbpiii, lbp);
    	
    }

}
